#include "LogManager.h"
#include <fstream>
#include <filesystem>
#include <iostream>
#include <QDir>
#include <QFileInfo>
#include <spdlog/sinks/stdout_color_sinks.h>


// 本文件禁止任何修改

namespace Common {

bool LogManager::init(const std::string& configFile) {
    if (m_initialized) {
        std::cout << "LogManager already initialized" << std::endl;
        return true;
    }

    try {
        // 读取配置文件
        std::ifstream f(configFile);
        if (!f.is_open()) {
            std::cerr << "Failed to open log config file: " << configFile << std::endl;
            return false;
        }

        json config = json::parse(f);

        // 遍历所有模块
        for (const auto& [name, module_config] : config.items()) {
            if (!createLogger(name, module_config)) {
                std::cerr << "Failed to create logger: " << name << std::endl;
                continue;
            }
        }

        // 确保main logger存在
        if (m_loggers.find("main") == m_loggers.end()) {
            auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
            console_sink->set_level(spdlog::level::trace);
            console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v");
            
            auto main_logger = std::make_shared<spdlog::logger>("main", console_sink);
            spdlog::register_logger(main_logger);
            m_loggers["main"] = main_logger;
        }

        m_initialized = true;
        return true;
    }
    catch (const std::exception& e) {
        std::cerr << "Failed to initialize LogManager: " << e.what() << std::endl;
        return false;
    }
}

bool LogManager::createLogger(const std::string& name, const json& config) {
    try {
        std::vector<spdlog::sink_ptr> sinks;
        
        // 创建所有sink
        for (const auto& sink_config : config["sinks"]) {
            auto sink = createSink(sink_config);
            if (sink) {
                sinks.push_back(sink);
            }
        }

        if (sinks.empty()) {
            std::cerr << "No valid sinks created for logger: " << name << std::endl;
            return false;
        }

        // 创建logger
        auto logger = std::make_shared<spdlog::logger>(name, sinks.begin(), sinks.end());
        
        // 设置logger级别
        if (config.contains("level")) {
            logger->set_level(parseLevel(config["level"]));
        }

        // 注册logger
        spdlog::register_logger(logger);
        m_loggers[name] = logger;
        return true;
    }
    catch (const std::exception& e) {
        std::cerr << "Failed to create logger " << name << ": " << e.what() << std::endl;
        return false;
    }
}

spdlog::sink_ptr LogManager::createSink(const json& config) {
    try {
        std::string type = config["type"];
        spdlog::sink_ptr sink;

        if (type == "daily") {
            std::string file_path = config["file_path"];
            
            // 只创建父目录
            QFileInfo fileInfo(QString::fromStdString(file_path));
            QDir dir = fileInfo.dir();
            if (!dir.exists()) {
                dir.mkpath(".");
            }

            int max_files = config.value("max_files", 30);
            sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>(
                file_path, 0, 0, false, max_files);
        }
        else if (type == "rotating") {
            std::string file_path = config["file_path"];
            
            // 只创建父目录
            QFileInfo fileInfo(QString::fromStdString(file_path));
            QDir dir = fileInfo.dir();
            if (!dir.exists()) {
                dir.mkpath(".");
            }

            size_t max_size = config.value("max_size", 1048576);
            int max_files = config.value("max_files", 10);
            sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
                file_path, max_size, max_files);
        }
        else if (type == "console") {
            auto color_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
            // 确保启用颜色
            color_sink->set_color_mode(spdlog::color_mode::always);
            sink = color_sink;
        }
        else {
            std::cerr << "Unknown sink type: " << type << std::endl;
            return nullptr;
        }

        // 设置sink属性
        if (config.contains("level")) {
            sink->set_level(parseLevel(config["level"]));
        }
        if (config.contains("pattern")) {
            sink->set_pattern(config["pattern"]);
        }

        return sink;
    }
    catch (const std::exception& e) {
        std::cerr << "Failed to create sink: " << e.what() << std::endl;
        return nullptr;
    }
}

spdlog::level::level_enum LogManager::parseLevel(const std::string& level) {
    if (level == "trace") return spdlog::level::trace;
    if (level == "debug") return spdlog::level::debug;
    if (level == "info") return spdlog::level::info;
    if (level == "warn") return spdlog::level::warn;
    if (level == "error") return spdlog::level::err;
    if (level == "critical") return spdlog::level::critical;
    if (level == "off") return spdlog::level::off;
    
    return spdlog::level::info;
}

std::shared_ptr<spdlog::logger> LogManager::getLogger(const std::string& name) {
    auto it = m_loggers.find(name);
    if (it != m_loggers.end()) {
        return it->second;
    }
    return m_loggers["main"];  // 返回默认logger
}

void LogManager::shutdown() {
    flush();
    spdlog::shutdown();
    m_loggers.clear();
    m_initialized = false;
}

void LogManager::flush() {
    for (const auto& [name, logger] : m_loggers) {
        if (logger) {
            logger->flush();
        }
    }
}

} // namespace Common